package models

import (
	"errors"
	"fmt"
	"strings"
	"sync"

	"github.com/astaxie/beego"

	"cvevulner/common"
	"cvevulner/util"

	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
)

var mutex sync.Mutex

// QueryIssueCveByNum query issue by cve num
func QueryIssueCveByNum(cvenum, repoPath string, organizationID int8) (GiteOriginIssue, bool) {
	o := orm.NewOrm()
	var cve GiteOriginIssue
	err := o.Raw("select * from cve_gite_origin_issue where "+
		"cve_number = ? and repo_path = ? and organizate_id = ?",
		cvenum, repoPath, organizationID).QueryRow(&cve)
	if err != nil {
		logs.Info("QueryIssueCveByNum, cve_gite_origin_issue, Can't find,"+
			" it's not an error, you need to add data, ", cvenum, repoPath)
		return cve, false
	} else {
		return cve, true
	}
}

// QueryIssue query issuewhitelist
func QueryIssueWhitelist(status int8) ([]IssueRepoWhitelist, error) {
	o := orm.NewOrm()
	var irw []IssueRepoWhitelist
	if status == 0 {
		num, err := o.Raw("select repo_id,package_name,version,branchs,status,create_time," +
			"update_time,delete_time" +
			" from cve_issue_repo_whitelist order by repo_id desc").QueryRows(&irw)
		if err == nil && num > 0 {
			logs.Info("QueryIssueWhitelist, search result: ", irw)
		} else {
			logs.Info("QueryIssueWhitelist, The current issue whitelist is empty, cur_time:",
				common.GetCurTime(), ",err: ", err)
		}
		return irw, err
	} else {
		num, err := o.Raw("select repo_id,package_name,version,branchs,status,create_time,"+
			"update_time,delete_time"+
			" from cve_issue_repo_whitelist where status = ? ", status).QueryRows(&irw)
		if err == nil && num > 0 {
			logs.Info("QueryIssueWhitelist, search result: ", irw)
		} else {
			logs.Info("QueryIssueWhitelist, The current issue whitelist is empty, cur_time:",
				common.GetCurTime(), ", err: ", err)
		}
		return irw, err
	}
}

// QueryIssue query center
func QueryIssueByPackName(packName, days string, prcnum int) ([]VulnCenter, error) {
	o := orm.NewOrm()
	var vc []VulnCenter
	num, err := o.Raw("select * from cve_vuln_center where pack_name = ? and "+
		"update_time >= ? and cve_status in (?, ?) "+
		"order by cve_id asc limit ?", packName, days, 0, 1, prcnum).QueryRows(&vc)
	if err == nil && num > 0 {
		logs.Info("QueryIssueByPackName, cve_vuln_center , search result：", vc, "Query conditions： packName: ", packName)
	} else {
		logs.Info("QueryIssueByPackName, cve_vuln_center, There is currently no cve, need to submit an issue, cur_time:",
			common.GetCurTime(), ", err: ", err)
	}
	return vc, err
}

// QueryIssue query center
func QueryIssue(days string, prcnum int, list []string) ([]VulnCenter, error) {
	o := orm.NewOrm()
	var vc []VulnCenter
	var num int64
	var err error
	if list != nil && len(list) > 0 {
		var s string
		for _, v := range list {
			s += "'" + v + "',"
		}
		if len(s) > 1 {
			s = s[:len(s)-1]
		}
		num, err = o.Raw(fmt.Sprintf("select * from cve_vuln_center where cve_num in (%s) and cve_status in (0, 1) "+
			"order by cve_id asc", s)).QueryRows(&vc)
	} else {
		num, err = o.Raw("select * from cve_vuln_center where cve_status in (0, 1) or (cve_status = 3 and create_time > ?) "+
			"order by cve_id asc ", "2025-07-01").QueryRows(&vc)
	}
	if err == nil && num > 0 {
		logs.Info("QueryIssue, cve_vuln_center, search result: ", vc)
	} else {
		logs.Info("QueryIssue, cve_vuln_center, There is currently no cve, need to submit an issue, cur_time:",
			common.GetCurTime(), ", err: ", err)
	}
	return vc, err
}

func GetVulnCenterByCVEID(vc *VulnCenter, cveId int64, fields ...string) error {
	o := orm.NewOrm()
	var fieldsStr string
	if len(fields) == 0 {
		fieldsStr = "*"
	} else {
		fieldsStr = strings.Join(fields, ",")
	}
	sqlStr := fmt.Sprintf(`select %v from cve_vuln_center where cve_id=?`, fieldsStr)
	err := o.Raw(sqlStr, cveId).QueryRow(vc)
	return err
}

// QueryIssueSecurity 查找安全公告
func QueryIssueSecurity(cveId int64, cveNum string) (SecurityNotice, error) {
	o := orm.NewOrm()
	var sn SecurityNotice
	err := o.Raw("select sec_id, cve_id,cve_num,openeuler_id,introduction,summary,theme,"+
		"description,influence_component,affect_product,reference_link"+
		" from cve_security_notice where cve_id = ? and cve_num = ?", cveId, cveNum).QueryRow(&sn)
	if err == nil {
		logs.Info("QueryIssueSecurity, cve_security_notice, search result:", sn)
	} else {
		logs.Info("QueryIssueSecurity, cve_security_notice, cveId: ", cveId, ", err: ", err)
	}
	return sn, err
}

func QueryIssueScore(cveId int64) (Score, error) {
	o := orm.NewOrm()
	var sc Score
	err := o.Raw("select *"+
		" from cve_score where cve_id = ?", cveId).QueryRow(&sc)
	if err == nil {
		logs.Info("QueryIssueScore, cve_score, search result: ", sc)
	} else {
		logs.Info("QueryIssueScore, cve_score, cveId: ", cveId, ", err: ", err)
	}
	return sc, err
}

func GetIssueTemplateByStatus(status int8, templateId int64, num int) (issueTemp []IssueTemplate, err error) {
	sql := `select * from cve_issue_template where status = %d and template_id > %d order by template_id limit %d`
	sql = fmt.Sprintf(sql, status, templateId, num)
	o := orm.NewOrm()
	_, err = o.Raw(sql).QueryRows(&issueTemp)
	return
}

func GetIssueTemplateByStatuss(id int64) (issueTemp IssueTemplate, err error) {
	sql := `select * from cve_issue_template where status < 4 and cve_id = %d`
	sql = fmt.Sprintf(sql, id)
	o := orm.NewOrm()
	err = o.Raw(sql).QueryRow(&issueTemp)
	return
}

func GetIssueTemplateByColName(it *IssueTemplate, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(it, colName...)
	return err
}

func GetSpecIssueAssignee(sia *SpecIssueAssigness, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(sia, colName...)
	return err
}

func UpdateIssueTemplate(it *IssueTemplate, fields ...string) error {
	logs.Info("Update===>", it, fields)
	o := orm.NewOrm()
	_, err := o.Update(it, fields...)
	return err
}

// query data
func QueryIssueTemplateAssociation(ita *IssueTemplateAssociation, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(ita, colName...)
	return err
}

// update data
func UpdateIssueTemplateAssociation(ita *IssueTemplateAssociation, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(ita, fields...)
	return err
}

func InsertIssueTemplateAssociation(ita *IssueTemplateAssociation) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(ita)
	return id, err
}

func UpdateScore(s *Score, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(s, fields...)
	return err
}

func UpdatePackageByCveId(pkgStr string, cveId int64) error {
	mutex.Lock()
	defer mutex.Unlock()
	if pkgStr == "" || cveId == 0 {
		return errors.New("param pkgStr,cveId must be not empty")
	}
	ps := strings.Split(pkgStr, ",")
	if len(ps) > 0 {
		sec := struct {
			SecId int64
		}{}
		secSql := `SELECT sec_id FROM cve_security_notice WHERE cve_id = ?`
		o := orm.NewOrm()
		err := o.Raw(secSql, cveId).QueryRow(&sec)
		if err != nil {
			return err
		}
		for _, v := range ps {
			tv := util.TrimString(v)
			if tv == "" {
				continue
			}
			pkg := Package{SecId: sec.SecId, PackName: tv}
			errx := o.Read(&pkg, "sec_id", "pack_name")
			if errx == orm.ErrNoRows {
				pkg.PackUrl = fmt.Sprintf(`https://repo.openeuler.org/openEuler-20.03-LTS/update/aarch64/Packages/%s`, tv)
				_, errx = o.Insert(&pkg)
			}
		}
		return nil
	}
	return nil
}

func ReplacePackageByCveId(pkgList []string, cveId int64, affectBranch string) error {
	sec := struct {
		SecId int64
	}{}
	secSql := `SELECT sec_id FROM cve_security_notice WHERE cve_id = ?`
	o := orm.NewOrm()
	err := o.Raw(secSql, cveId).QueryRow(&sec)
	if err != nil {
		return err
	}
	delPkgSql := `DELETE FROM cve_package WHERE sec_id = ? and affect_product = ?`
	_, err = o.Raw(delPkgSql, sec.SecId, affectBranch).Exec()
	if err != nil {
		logs.Error("ReplacePackageByCveId, delete cve_package error:", err)
	}
	pkgData := make([]Package, 0)
	for _, v := range pkgList {
		if strings.Trim(v, " ") == "" {
			continue
		}
		platform := "source"
		if strings.Contains(v, ".x86_64.") {
			platform = "x86_64"
		} else if strings.Contains(v, ".aarch64.") || strings.Contains(v, ".noarch.") {
			platform = "aarch64"
		}
		pkgUrl := fmt.Sprintf(`https://repo.openeuler.org/%s/update/%s/Packages/%s`, affectBranch, platform, v)
		pv := Package{SecId: sec.SecId, PackName: v, PackUrl: pkgUrl, AffectProduct: affectBranch, Source: platform}
		pkgData = append(pkgData, pv)
	}
	_, err = o.InsertMulti(1, pkgData)
	return err
}

func QueryPackageByCveId(cveId int64) ([]Package, error) {
	sqlStr := `SELECT * FROM cve_package WHERE sec_id = (SELECT sec_id FROM cve_security_notice WHERE cve_id = ?)`
	var res []Package
	o := orm.NewOrm()
	_, err := o.Raw(sqlStr, cveId).QueryRows(&res)
	return res, err
}

func InsertIssueTemplate(it *IssueTemplate) (issTempId int64, err error) {
	o := orm.NewOrm()
	if issTempId, err = o.Insert(it); err == nil && issTempId > 0 {
		logs.Info("InsertIssueTemplate, insert cve_issue_template success, issTempId: ",
			issTempId, "cveNum: ", it.CveNum)
	} else {
		logs.Error("InsertIssueTemplate, insert cve_issue_template failed, cveNum:",
			it.CveNum, ", err: ", err)
		return 0, err
	}
	return issTempId, nil
}

func UpdateIssueTemplateAll(it *IssueTemplate) (issTempId int64, err error) {
	o := orm.NewOrm()
	if num, err := o.Update(it); err == nil {
		logs.Info("UpdateIssueTemplateAll, update cve_issue_template success, num: ", num, "cveNum: ", it.CveNum)
	} else {
		logs.Error("UpdateIssueTemplateAll, update cve_issue_template failed, cveNum:",
			it.CveNum, ", err: ", err)
		return 0, err
	}
	return it.TemplateId, nil
}

func DeleteIssueTemplate(issTempId int64) error {
	o := orm.NewOrm()
	var it = IssueTemplate{TemplateId: issTempId}
	id, dErr := o.Delete(&it)
	if dErr == nil && id > 0 {
		logs.Info("DeleteIssueTemplate, delete cve_issue_template success, issTempId: ", issTempId)
	} else {
		logs.Error("DeleteIssueTemplate, delete cve_issue_template failed, issTempId: ",
			issTempId, ", err: ", dErr)
	}
	return dErr
}

func CreateIssueTemplate(it *IssueTemplate) (issTempId int64, err error) {
	o := orm.NewOrm()
	if it.TemplateId == 0 {
		var issTempId int64
		if issTempId, err = o.Insert(it); err == nil {
			logs.Info("CreateIssueTemplate, insert cve_issue_template success, "+
				"issTempId: ", issTempId, ", cveNum: ", it.CveNum)
		} else {
			logs.Error("CreateIssueTemplate, insert cve_issue_template failed, cveNum:",
				it.CveNum, ", err: ", err)
			return 0, err
		}
		return issTempId, nil
	} else {
		if num, err := o.Update(it); err == nil {
			logs.Info("CreateIssueTemplate, update cve_issue_template success, "+
				"num: ", num, ", cveNum: ", it.CveNum)
		} else {
			logs.Error("CreateIssueTemplate, update cve_issue_template failed, "+
				"cveNum:", it.CveNum, ", err: ", err)
			return 0, err
		}
		return it.TemplateId, nil
	}
}

func GetAllIssueHook(hookId int64, count, status int) (localh []IssueHooks, value bool) {
	o := orm.NewOrm()
	var localIh []IssueHooks
	var num int64
	num, err := o.Raw("select *"+
		" from cve_issue_hooks where status = ? and id > ? order by id limit ?",
		status, hookId, count).QueryRows(&localIh)
	if err == nil && num > 0 {
		return localIh, true
	} else {
		logs.Info("GetAllIssueHook, cve_issue_hooks, err: ", err)
		return localIh, false
	}
}

func UpdateIssueHook(id int64, status int8) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_issue_hooks SET status = ? WHERE id = ?", status, id).QueryRow()
	return
}

func GetIssueHook(ih *IssueHooks) (localh []IssueHooks, value bool) {
	o := orm.NewOrm()
	var localIh []IssueHooks
	var num int64
	num, err := o.Raw("select *"+
		" from cve_issue_hooks where owner = ? and repo = ? and status = ?",
		ih.Owner, ih.Repo, ih.Status).QueryRows(&localIh)
	if err == nil && num > 0 {
		return localIh, true
	} else {
		logs.Info("GetIssueHook, cve_issue_hooks, "+
			"cveId: ", ih.CveId, ", err: ", err)
		return localIh, false
	}
}

func CreateDepositHooks(ih *IssueHooks) (issHookId int64, err error) {
	o := orm.NewOrm()
	var localIh IssueHooks
	localIh.CveId = ih.CveId
	localIh.IssueNum = ih.IssueNum
	errx := o.Raw("select *"+
		" from cve_issue_hooks where owner = ? and repo = ? and status = ?",
		ih.Owner, ih.Repo, ih.Status).QueryRow(&localIh)
	if errx == nil {
		ih.Id = localIh.Id
		if num, err := o.Update(ih); err == nil {
			logs.Info("CreateDepositHooks, update cve_issue_hook success, "+
				"issHookId: ", num, "IssueNum: ", ih.IssueNum)
		} else {
			logs.Error("CreateDepositHooks, update cve_issue_hook failed, "+
				"IssueNum:", ih.IssueNum, ", err: ", err)
			return 0, err
		}
		return ih.Id, nil
	} else {
		var issHookId int64
		if issHookId, err = o.Insert(ih); err == nil {
			logs.Info("CreateDepositHooks, insert cve_issue_hook success, "+
				"issHookId: ", issHookId, ", IssueNum: ", ih.IssueNum)
		} else {
			logs.Error("CreateDepositHooks, insert cve_issue_hook failed, "+
				"IssueNum:", ih.IssueNum, ", err: ", err)
			return 0, err
		}
		return issHookId, nil
	}
}

func UpdateSecNotice(sec *SecurityNotice) (secId int64, err error) {
	o := orm.NewOrm()
	var localSec SecurityNotice
	localSec.CveId = sec.CveId
	localSec.CveNum = sec.CveNum
	errx := o.Raw("select *"+
		" from cve_security_notice where cve_id = ? and cve_num = ?",
		sec.CveId, sec.CveNum).QueryRow(&localSec)
	if errx == nil {
		sec.SecId = localSec.SecId
		sec.OpenId = localSec.OpenId
		sec.InfluenceComponent = localSec.InfluenceComponent
		sec.Description = localSec.Description
		sec.Summary = localSec.Summary
		sec.AffectStatus = localSec.AffectStatus
		sec.Status = localSec.Status
		sec.ReferenceLink = localSec.ReferenceLink
		if num, err := o.Update(sec); err == nil {
			logs.Info("UpdateSecNotice, update cve_security_notice success, "+
				"SecID: ", num, ",CveNum: ", sec.CveNum)
		} else {
			logs.Error("UpdateSecNotice, update cve_security_notice failed, "+
				"SecID:", sec.SecId, ", err: ", err)
			return 0, err
		}
		return sec.SecId, nil
	} else {
		var SecId int64
		if SecId, err = o.Insert(sec); err == nil {
			logs.Info("UpdateSecNotice, insert cve_security_notice success, "+
				"SecID: ", SecId, ", CveNum: ", sec.CveNum)
		} else {
			logs.Error("UpdateSecNotice, insert cve_security_notice failed, "+
				"CveNum:", sec.CveNum, ", err: ", err)
			return 0, err
		}
		return SecId, nil
	}
}

func UpdateIssueStatus(iss VulnCenter, status int8) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_vuln_center SET cve_status = ? WHERE cve_id = ? and cve_num = ?",
		status, iss.CveId, iss.CveNum).QueryRow()
	return
}

func UpdateLockIssueStatus(beStatus, afStatus int8) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_vuln_center SET cve_status = ? WHERE cve_status = ?",
		afStatus, beStatus).QueryRow()
	return
}

func GetIssueSpecErrByColName(se *SpecError, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(se, colName...)
	return err
}

func GetOrgCveDesc(ord *OriginUpstreamDesc, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(ord, colName...)
	return err
}

func LockUpdateIssueStatus(cveId int64, cveNum string, status int8) bool {
	o := orm.NewOrm()
	res, err := o.Raw("UPDATE cve_vuln_center SET cve_status = ? "+
		"WHERE cve_id = ? and cve_num = ? and cve_status in (0,1)",
		status, cveId, cveNum).Exec()
	if err == nil {
		num, _ := res.RowsAffected()
		if num > 0 {
			logs.Info("LockUpdateIssueStatus, update cve_vuln_center row affected "+
				"nums: ", num, ",cveId: ", cveId)
			return true
		}
		return false
	} else {
		logs.Error("LockUpdateIssueStatus, update cve_vuln_center failed, "+
			"cveId: ", cveId, ", err: ", err)
		return false
	}
}

func UnLockUpdateIssueStatus(beforeStatus, afterStatus int8, updateTime, beforeTime string) bool {
	o := orm.NewOrm()
	res, err := o.Raw("UPDATE cve_vuln_center SET cve_status = ?,update_time = ? WHERE cve_status = ? and update_time < ?",
		afterStatus, updateTime, beforeStatus, beforeTime).Exec()
	if err == nil {
		num, _ := res.RowsAffected()
		if num > 0 {
			logs.Info("UnLockUpdateIssueStatus, update cve_vuln_center row affected nums: ", num)
			return true
		}
		return false
	} else {
		logs.Error("UnLockUpdateIssueStatus, update cve_vuln_center failed, cve_vuln_center, err: ", err)
		return false
	}
}

func UpdateIssueScore(iss VulnCenter, status int8) (id int64) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_score SET n_score_status = ? WHERE cve_id = ? and cve_num = ?",
		status, iss.CveId, iss.CveNum).QueryRow()
	return
}

func UpdateIssueScoreRe(iss VulnCenter, status int8) (id int64) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_score_record SET status = ? WHERE cve_id = ? and status = ?",
		status, iss.CveId, 0).QueryRow()
	return
}

func UpdateIssueCommentId(issueNum, cveNum string, commentId int64) (id int64) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_issue_template SET comment_id = ? WHERE issue_num = ? and cve_num = ?",
		commentId, issueNum, cveNum).QueryRow()
	return
}

// IssueExistByNumber Determine whether the issue exists
func IssueExistByNumber(number string, id int64) bool {
	if number == "" {
		return false
	}
	o := orm.NewOrm()
	exit := o.QueryTable("cve_issue_template").Filter("issue_num", number).Filter("issue_id", id).Exist()
	return exit
}

func GetIssueTplByCveNum(num string) (list []IssueTemplate, err error) {
	o := orm.NewOrm()
	_, err = o.QueryTable("cve_issue_template").Filter("cve_num", num).All(&list)
	return
}

func CreateIssueRecord(icr *IssueCreateRecord) (issueRecordId int64, err error) {
	o := orm.NewOrm()
	var localIcr IssueCreateRecord
	errx := o.Raw("select *"+
		" from cve_issue_create_record where cve_id = ? and cve_num = ? and cve_version = ?",
		icr.CveId, icr.CveNum, icr.CveVersion).QueryRow(&localIcr)
	if errx != nil || localIcr.IssueRecordId == 0 {
		var issueRecordId int64
		if issueRecordId, err = o.Insert(icr); err == nil {
			logs.Info("CreateIssueRecord, insert cve_issue_create_record success, "+
				"issueRecordId: ", issueRecordId, ", cveNum: ", icr.CveNum)
		} else {
			logs.Error("CreateIssueRecord, insert cve_issue_create_record failed, "+
				"cveData:", icr, ", err: ", err)
			return 0, err
		}
		return issueRecordId, nil
	} else {
		icr.IssueRecordId = localIcr.IssueRecordId
		if num, err := o.Update(icr); err == nil {
			logs.Info("CreateIssueRecord, update cve_issue_create_record success,"+
				" num: ", num, ", cveNum: ", icr.CveNum)
		} else {
			logs.Error("CreateIssueRecord, update cve_issue_create_record failed,"+
				" cveData:", icr, ", err: ", err)
			return 0, err
		}
		return icr.IssueRecordId, nil
	}
}

// QueryIssue query center
func QueryIssueTemplateByTime(beforeTime string, prcnum int,
	templateId int64, status int8) ([]IssueTemplate, error) {
	o := orm.NewOrm()
	var it []IssueTemplate
	num, err := o.Raw("select *"+
		" from cve_issue_template where create_time >= ? and status < ? and template_id > ? "+
		"order by template_id asc limit ?", beforeTime, status, templateId, prcnum).QueryRows(&it)
	if err == nil && num > 0 {
		return it, nil
	}
	return it, err
}

func QueryIssueTemplateByLink(beforeTime string, prcnum int,
	templateId int64, status int8) ([]IssueTemplate, error) {
	o := orm.NewOrm()
	var it []IssueTemplate
	num, err := o.Raw("select *"+
		" from cve_issue_template where status in (1,2,3,5) "+
		"and template_id > ? "+
		"order by template_id asc limit ?", templateId, prcnum).QueryRows(&it)
	if err == nil && num > 0 {
		return it, nil
	}
	return it, err
}

func QueryAllCveVuln(prcnum int, cveId int64) ([]VulnCenter, error) {
	o := orm.NewOrm()
	var vc []VulnCenter
	num, err := o.Raw("select *"+
		" from cve_vuln_center where cve_id > ? "+
		"order by cve_id asc limit ?", cveId, prcnum).QueryRows(&vc)
	if err == nil && num > 0 {
		return vc, nil
	}
	return vc, err
}

func QueryIssueStatisticEmail() ([]IssueStatisticsMailList, error) {
	o := orm.NewOrm()
	var ism []IssueStatisticsMailList
	num, err := o.Raw("SELECT * FROM cve_issue_statistics_mail_list").QueryRows(&ism)
	logs.Info("cve_issue_statistics_mail_list: ", num, err)
	return ism, err
}

func QueryLowCredibilityCve(days string, prcnum,
	credibilityLevel int, cveId int64) ([]OriginUpstream, int64, error) {
	o := orm.NewOrm()
	var gs []OriginUpstream
	num, err := o.Raw("select cve_id,cve_un_ids,cve_num, update_type,cve_packname,"+
		"git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date,"+
		"vul_status,cve_status,version,credibility_level"+
		" from cve_origin_upstream where update_time >= ? and cve_status in (?, ?) "+
		" and credibility_level > ? and cve_id > ? "+
		"order by cve_id asc limit ?", days, 0, 1, credibilityLevel, cveId, prcnum).QueryRows(&gs)
	if err == nil && num > 0 {
		logs.Info("QueryLowCredibilityCve, cve_origin_upstream, serach result: ", num)
	} else {
		logs.Info("QueryLowCredibilityCve, There is currently no new or updated cve, cur_time:",
			common.GetCurTime(), "err: ", err)
	}
	return gs, num, err
}

func UpdateTempleteError(errDesc, cveNum string, cveId int64) (id int64) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_issue_template SET error_description = ?, update_time = ? WHERE cve_id = ? and cve_num = ?",
		errDesc, common.GetCurTime(), cveId, cveNum).QueryRow()
	return 0
}

func QueryGiteOriginIssue(cveNum, path string, organizationID int8) (gi []GiteOriginIssue) {
	o := orm.NewOrm()
	_, err := o.Raw("select * from cve_gite_origin_issue where "+
		"cve_number = ? and repo_path = ? and organizate_id = ?",
		cveNum, path, organizationID).QueryRows(&gi)
	if err != nil {
		logs.Error("QueryGiteOriginIssue, err: ", err)
	}
	return
}

func QueryEulerOriginBRepo(packName, branch string) (ori []OpenEulerRepoOrigin) {
	o := orm.NewOrm()
	brandStr := "%" + branch + "%"
	sql := fmt.Sprintf(`select * from cve_open_euler_repo_origin where package_name='%s' and branch like '%s' order by update_time desc`, packName, brandStr)
	logs.Info("sql===> ", sql)
	num, err := o.Raw(sql).QueryRows(&ori)
	if err == nil && num > 0 {
		logs.Info("QueryEulerOriginBRepo, cve_open_euler_repo_origin, search result: ", ori)
	} else {
		logs.Info("QueryEulerOriginBRepo, cve_open_euler_repo_origin, There is currently no cve, need to submit an issue, cur_time:",
			common.GetCurTime(), ", err: ", err)
	}
	return
}

func GetCommunityYamlConfigAll() (cyc []CommunityYamlConfig) {
	o := orm.NewOrm()
	num, getErr := o.Raw("select table_name,organizate_id" +
		" from cve_community_yaml_config order by id asc").QueryRows(&cyc)
	if num == 0 {
		logs.Error("GetCommunityYamlConfigAll, Get data does not exist, getErr: ", getErr)
	}
	return
}

func InsertCommunityYamlConfig(cyc *CommunityYamlConfig) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(cyc)
	return id, err
}

type CommunityPackage struct {
	Id             int64  `orm:"column(id)"`
	PackageName    string `orm:"column(package_name)" description:"组件名称"`
	PackageVersion string `orm:"column(version)" description:"组件版本"`
	RepoName       string `orm:"column(repo_name)" description:"仓库名称"`
}

func GetCommunityYamlList(table string, id int64, count int) (cp []CommunityPackage) {
	o := orm.NewOrm()
	sql := fmt.Sprintf("select id,package_name,version,repo_name from %s "+
		"where id > %d order by id asc limit %d", table, id, count)
	num, getErr := o.Raw(sql).QueryRows(&cp)
	if num == 0 {
		logs.Error("GetCommunityYamlList, Get data does not exist, geErr: ", getErr)
	}
	return
}

func QueryOriginUpstreamByName(pkName string, credibilityLevel int) (ous []OriginUpstream) {
	o := orm.NewOrm()
	packageName := "%" + pkName + "%"
	sql := fmt.Sprintf("select * from cve_origin_upstream where "+
		"credibility_level <= %d and git_packname like '%s' ORDER BY cve_id DESC", credibilityLevel, packageName)
	//logs.Info("sql: ", sql)
	num, getErr := o.Raw(sql).QueryRows(&ous)
	if num == 0 {
		logs.Error("QueryOriginUpstreamByName, Get data does not exist, geErr: ", getErr)
	}
	return
}

func QueryIssueCommunityStatistics(eoi *IssueCommunityStatistics, field ...string) error {
	o := orm.NewOrm()
	err := o.Read(eoi, field...)
	return err
}

// insert data
func InsertIssueCommunityStatistics(eoi *IssueCommunityStatistics) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(eoi)
	return id, err
}

func UpdateOriginUpstream(eoi *OriginUpstream, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(eoi, fields...)
	return err
}

func QueryAuthTokenInfo() []AuthTokenInfo {
	o := orm.NewOrm()
	var ati []AuthTokenInfo
	num, err := o.Raw("select * from cve_auth_token_info order by id ").QueryRows(&ati)
	if err != nil {
		logs.Info("QueryAuthTokenInfo, num: ", num, ", err: ", err)
	}
	return ati
}

func UpdateAuthTokenInfoById(ati AuthTokenInfo) (id int64) {
	o := orm.NewOrm()
	_ = o.Raw("UPDATE cve_auth_token_info SET access_token = ?, token_type = ?, expires_in = ?, "+
		"refresh_token = ?, scope = ?, created_at = ?, update_time = ? WHERE id = ? ",
		ati.AccessToken, ati.TokenType, ati.ExpiresIn, ati.RefreshToken,
		ati.Scope, ati.CreatedAt, ati.UpdateTime, ati.Id).QueryRow()
	return 0
}

func QueryAuthTokenById(ati *AuthTokenInfo, colName ...string) error {
	o := orm.NewOrm()
	err := o.Read(ati, colName...)
	return err
}

// IsIssueWithAnalysisVersion returns whether the issue has an analysis version.
func (t *IssueTemplate) IsIssueWithAnalysisVersion() bool {
	return t.AnalysisVersion != ""
}

// IsIssueComplete returns whether the issue is completed.
func (t *IssueTemplate) IsIssueComplete() bool {
	const StatusCompleted = 3
	return t.Status == StatusCompleted
}

// HasAffected checks if the issue has affected versions based on the AnalysisVersion field.
func (t *IssueTemplate) HasAffected() bool {
	const ExpectedItemLength = 2
	split := strings.Split(t.AnalysisVersion, ",")
	for _, v := range split {
		item := strings.Split(v, ":")
		if len(item) != ExpectedItemLength || item[1] == "" {
			continue
		}

		_, ok := common.AnalysisUnaffected[item[1]]
		if !ok {
			return true
		}
	}

	return false
}

// ContainsWillFix checks if the AnalysisVersion contains the common.AnalysisWillFix string.
func (t *IssueTemplate) ContainsWillFix() bool {
	return strings.Contains(t.AnalysisVersion, common.AnalysisWillFix)
}

// IsAllUnaffected splits the AnalysisVersion by commas and checks if all parts are unaffected.
func (t *IssueTemplate) IsAllUnaffected() bool {
	const splitLen = 2
	split := strings.Split(t.AnalysisVersion, ",")
	for _, v := range split {
		item := strings.Split(strings.ReplaceAll(v, "：", ":"), ":")
		if len(item) != splitLen {
			return false
		}

		if _, ok := common.AnalysisUnaffected[item[1]]; !ok {
			return false
		}
	}

	return true
}

// ResetLabel resets the issue label based on whether the issue is all unaffected or fixed.
func (t *IssueTemplate) ResetLabel() {
	if t.IsAllUnaffected() {
		t.IssueLabel = beego.AppConfig.String("labeUnaffected")
	} else {
		t.IssueLabel = beego.AppConfig.String("labelFixed")
	}
}

// HasBranch issue的分析说明分支是否包含指定分支
func (t *IssueTemplate) HasBranch(branch string) bool {
	split := strings.Split(t.AffectedVersion, ",")
	for _, v := range split {
		item := strings.Split(v, ":")
		if len(item) == 0 {
			continue
		}

		if item[0] == branch {
			return true
		}
	}

	return false
}
